package com.greateamd.timetableasy.domain;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import net.sf.gilead.pojo.gwt.LightEntity;

import com.greateamd.timetableasy.client.domain.AuthType;

@SuppressWarnings("serial")
@Entity
@Table(name="users")
public class User extends LightEntity implements PersistableEntity,HasEventsEntity,Serializable
{

	@Id
	private String username;
	
	@Column(name="firstname",nullable=false)
	private String firstname;

	@Column(name="lastname",nullable=false)
	private String lastname;
	
	@Column(name="address",nullable=false)
	private String address;
	
	@Column(name="age",nullable=false)
	private Integer age;
	
	@Column(name="password",nullable=false)
	private String password;
	
	@Column(name="enabled",nullable=false)
	private boolean enabled;

	@OneToMany(mappedBy="user", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
	private Set<Auth> auths;
	
	@ManyToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="id_promotion", referencedColumnName="id")
	private Promotion promotion;
	
//	@ManyToMany(fetch = FetchType.LAZY,targetEntity=User.class,cascade=CascadeType.ALL)
//    @JoinTable(name="users_followed",
//		        joinColumns = @JoinColumn(columnDefinition="user_username"),
//		        inverseJoinColumns=@JoinColumn(name="followed_username"))
//	private Set<User> followed;

	@ManyToMany(fetch = FetchType.LAZY,targetEntity=Event.class,cascade=CascadeType.ALL)
    @JoinTable(name="users_events",
		        joinColumns = @JoinColumn(columnDefinition="user"),
		        inverseJoinColumns=@JoinColumn(name="event_id"))
	private Set<Event> events;
	
	public User()
	{}

	public User(String username,String firstname,String lastname,String address,int age, String password, boolean enabled) 
	{
		this.username = username;
		this.firstname = firstname;
		this.lastname = lastname;
		this.address = address;
		this.age = age;
		this.password = password;
		this.enabled = enabled;
	}

	public String getUsername() 
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public String getFirstname() {
		return firstname;
	}

	public String getLastname() {
		return lastname;
	}

	public String getAddress() {
		return address;
	}

	public Integer getAge() {
		return age;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getPassword() 
	{
		return password;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

	public boolean isEnabled() 
	{
		return enabled;
	}

	public void setEnabled(boolean enabled)
	{
		this.enabled = enabled;
	}

	public Set<Auth> getAuths() {
		return auths;
	}

	public void setAuths(Set<Auth> auths) {
		this.auths = auths;
	}

	public Promotion getPromotion() {
		return promotion;
	}

	public void setPromotion(Promotion promotion) {
		this.promotion = promotion;
	}

	public void addAuth(Auth auth) {
		if (auths == null)
			auths = new HashSet<Auth>();
		this.auths.add(auth);
	}
	
	public void addEvent(Event e) {
		if (events == null)
			events = new HashSet<Event>();
		this.events.add(e);
	}
	
	public boolean containsAuth(AuthType authType){
		for(Auth auth : auths){
			if(auth.getAuthority().equals(authType.name())){
				return true;
			}
		}
		return false;
	}

	public Set<Event> getEvents() {
		return events;
	}

	public void setEvents(Set<Event> events) {
		this.events = events;
	}

	@Override
	public Serializable getId() {
		return username;
	}
	
	@Override
	public int hashCode() {
		if(getUsername()!=null)
			return getUsername().hashCode();
		else return 0;
	}
	
	@Override
	public boolean equals(Object obj) {
		if( obj != null && obj instanceof User ){
			if(((User)obj).getUsername().compareToIgnoreCase(getUsername()) == 0){
				return true;
			}
		}
		return false;
	}
	
	@Override
	public String toString() {
		return getUsername();
	}
}
